package one.stand.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.vioao.wechat.api.component.ComponentApi;
import com.github.vioao.wechat.api.component.wxa.CodeApi;
import com.github.vioao.wechat.bean.MediaFile;
import com.github.vioao.wechat.bean.entity.component.wxa.Category;
import com.github.vioao.wechat.bean.entity.component.wxa.Commit;
import com.github.vioao.wechat.bean.entity.component.wxa.SubmitAudit;
import com.github.vioao.wechat.bean.entity.component.wxa.SubmitAudit.Item;
import com.github.vioao.wechat.bean.response.BaseResponse;
import com.github.vioao.wechat.bean.response.component.GetAuthorizerInfoResponse;
import com.github.vioao.wechat.bean.response.component.wxa.GetAuditstatusResponse;
import com.github.vioao.wechat.bean.response.component.wxa.GetCategoryResponse;
import com.github.vioao.wechat.bean.response.component.wxa.GetPageResponse;
import com.jmp.autocofiguration.util.OssUtil2;
import com.jmp.base.dto.*;
import com.jmp.feign.AccountFeign;
import com.jmp.feign.WechatFeign;
import lombok.extern.slf4j.Slf4j;
import one.stand.code.RedisCode;
import one.stand.config.ComponentConfig;
import one.stand.config.ExtJsonConfig;
import one.stand.enums.CompanyVersionEnums;
import one.stand.mapper.CompanyVersionMapper;
import one.stand.mapper.VersionMapper;
import one.stand.model.CompanyVersionModel;
import one.stand.model.ResultModel;
import one.stand.model.VersionModel;
import one.stand.service.CodeService;
import one.stand.util.AssertUtil;
import one.stand.util.DateUtil;
import one.stand.util.RedisUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * @author: QIK
 * @CreateDate: 2019/5/13 12:02
 */
@Service
@Slf4j
public class CodeServiceImpl implements CodeService {
    private ComponentApi componentApi = new ComponentApi();

    @Autowired
    private AccountFeign accountFeign;
    @Autowired
    private WechatFeign wechatFeign;

    @Autowired
    private ComponentConfig componentConfig;
    @Lazy
    @Autowired
    private ExtJsonConfig extJsonConfig;
    /**
     * 小程序代码版本管理
     */
    @Autowired
    protected VersionMapper versionMapper;
    @Autowired
    protected CompanyVersionMapper companyVersionMapper;
    @Autowired
    protected RedisUtil redisUtil;

    @Override
    public BaseResponse commit(String appId, Integer versionId, boolean submitAudit) {
        ResultModel<WechatAuthorizerTokenResponse> authorizerTokenResponseResultModel = wechatFeign.authorizerToken(WechatAuthorizerTokenRequest.builder().appId(appId).build());
        AssertUtil.isTrue(authorizerTokenResponseResultModel);
        String token = authorizerTokenResponseResultModel.getData().getToken();
        BaseResponse baseResponse = new BaseResponse();
        if (StringUtils.isBlank(token)) {
            baseResponse.setErrmsg("账号未授权");
            baseResponse.setErrcode(61003);
        }
        VersionModel outModel = versionMapper.selectByPrimaryKey(versionId);
        AccountAppIdRequest accountAppIdRequest = AccountAppIdRequest.builder()
                .appId(appId)
                .build();
        ResultModel<AccountResponse> accountResponseResultModel = accountFeign.getByAppId(accountAppIdRequest);
        AssertUtil.isTrue(accountResponseResultModel);
        AccountResponse accountModel = accountResponseResultModel.getData();
        String companyKey = accountModel.getCompanyKey();
        String jumpAppid = null;
        String jumpName = null;
        String myAppName = accountModel.getAppName();
        Integer accountId = accountModel.getAccountId();
        ResultModel<WechatComponentTokenResponse> componentTokenResponseResultModel = wechatFeign.componentToken();
        AssertUtil.isTrue(componentTokenResponseResultModel);
        GetAuthorizerInfoResponse response = componentApi.getAuthorizerInfo(componentTokenResponseResultModel.getData().getToken(), componentConfig.getAppid(), appId);

        String headImg = "";
        if (response.getAuthorizerInfo() != null) {
            headImg = response.getAuthorizerInfo().getHeadImg();
        }
        log.info("设置头像：{}", headImg);
        if (null != outModel) {
            String json = extJsonConfig.getExtJSON(appId, jumpAppid, jumpName, companyKey, headImg, myAppName).toJSONString();
            log.info("最后的ext_json:{}", json);
            Commit commit = Commit.builder().extJson(json).templateId(outModel.getTemplateId()).userDesc(outModel.getDesc()).userVersion(outModel.getVersionNum()).build();
            baseResponse = CodeApi.commit(token, commit);
        }
        CompanyVersionModel companyVersionModel = new CompanyVersionModel();
        companyVersionModel.setAccountId(accountId);
        companyVersionModel.setVersionId(versionId);
        companyVersionModel.setRemark(baseResponse.toString());
        companyVersionModel.setCreateTime(DateUtil.currentDate());
        if (baseResponse.getErrcode().equals(0)) {
            log.info("代码提交成功：{}", appId);
            companyVersionModel.setState(CompanyVersionEnums.commit_success.getCode());
            companyVersionMapper.insertSelective(companyVersionModel);
            log.info("是否进行代码审核提交：{}", submitAudit);
            if (submitAudit) {
                submitAudit(versionId, appId);
            }
        } else {
            log.info("代码提交失败：{}-{}", appId, baseResponse.toString());
            companyVersionModel.setState(CompanyVersionEnums.commit_err.getCode());
            companyVersionMapper.insertSelective(companyVersionModel);
        }
        return baseResponse;
    }

    @Override
    public String getQrCode(String appid) {
        try {
            String url = redisUtil.get(RedisCode.getQrCodeKey(appid));
            if (StringUtils.isBlank(url)) {
                ResultModel<WechatAuthorizerTokenResponse> authorizerTokenResponseResultModel = wechatFeign.authorizerToken(WechatAuthorizerTokenRequest.builder().appId(appid).build());
                AssertUtil.isTrue(authorizerTokenResponseResultModel);
                String token = authorizerTokenResponseResultModel.getData().getToken();
                MediaFile mediaFile = CodeApi.getQrCode(token);
                InputStream inputStream = upload(mediaFile.getBufferedImage(), mediaFile.getSuffix());
                url = OssUtil2.upload(inputStream, mediaFile.getSuffix());
                if (StringUtils.isNoneBlank(url)) {
                    redisUtil.set(RedisCode.getQrCodeKey(appid), url);
                }
            }
            log.info("获取体验码：{}", url);
            return url;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            log.info("获取体验码失败：{}", appid);
            return null;
        }

    }

    public InputStream upload(BufferedImage bimg, String frefix) throws IOException {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        //保存新图片
        ImageIO.write(bimg, frefix, os);
        InputStream is = new ByteArrayInputStream(os.toByteArray());
        return is;
    }

    @Override
    public BaseResponse submitAudit(Integer versionId, String appId) {
        CompanyVersionModel companyVersionModel = companyVersionMapper.selectAccountById(new CompanyVersionModel() {{
            setVersionId(versionId);
            setAppId(appId);
        }});
        if (null == companyVersionModel) {
            log.info("获取版本数据为空：{}", versionId);
            return null;
        } else {
            ResultModel<WechatAuthorizerTokenResponse> authorizerTokenResponseResultModel = wechatFeign.authorizerToken(WechatAuthorizerTokenRequest.builder().appId(companyVersionModel.getAppId()).build());
            AssertUtil.isTrue(authorizerTokenResponseResultModel);
            String token = authorizerTokenResponseResultModel.getData().getToken();
            GetCategoryResponse response = CodeApi.getCategory(token);
            GetPageResponse getPageResponse = CodeApi.getPage(token);
            if (null == getPageResponse.getPageList() || getPageResponse.getPageList().size() <= 0) {
                //添加默认值
                List<String> list = new ArrayList<>();
                list.add("pages/index/main");
                getPageResponse.setPageList(list);
            }
            List<Category> list = response.getCategoryList();
            List<Item> itemList = new ArrayList<>();
            list.forEach(l -> {
                Item item = Item.builder()
                        .address(getPageResponse.getPageList().get(0))
                        .firstClass(l.getFirstClass())
                        .firstId(l.getFirstId())
                        .secondClass(l.getSecondClass())
                        .secondId(l.getSecondId())
                        .title("one").build();
                itemList.add(item);
            });
            SubmitAudit submitAudit = new SubmitAudit(itemList);
            BaseResponse baseResponse = CodeApi.submitAudit(token, submitAudit);
            if (baseResponse.getErrcode().equals(0)) {
                companyVersionModel.setState(CompanyVersionEnums.in_audit.getCode());
            } else {
                companyVersionModel.setState(CompanyVersionEnums.commit_audit.getCode());
            }
            companyVersionModel.setRemark(JSON.toJSONString(baseResponse));
            companyVersionMapper.updateByPrimaryKeySelective(companyVersionModel);
            return baseResponse;
        }
    }

    @Override
    public GetCategoryResponse getCategory(String appid) {
        ResultModel<WechatAuthorizerTokenResponse> authorizerTokenResponseResultModel = wechatFeign.authorizerToken(WechatAuthorizerTokenRequest.builder().appId(appid).build());
        AssertUtil.isTrue(authorizerTokenResponseResultModel);
        String token = authorizerTokenResponseResultModel.getData().getToken();
        return CodeApi.getCategory(token);
    }

    @Override
    public GetPageResponse getPage(String appid) {
        ResultModel<WechatAuthorizerTokenResponse> authorizerTokenResponseResultModel = wechatFeign.authorizerToken(WechatAuthorizerTokenRequest.builder().appId(appid).build());
        AssertUtil.isTrue(authorizerTokenResponseResultModel);
        String token = authorizerTokenResponseResultModel.getData().getToken();
        return CodeApi.getPage(token);
    }

    @Override
    public GetAuditstatusResponse getLatestAuditStatus(Integer versionId, String appId, boolean release) {
        CompanyVersionModel companyVersionModel = companyVersionMapper.selectAccountById(new CompanyVersionModel() {{
            setVersionId(versionId);
            setAppId(appId);
        }});
        ResultModel<WechatAuthorizerTokenResponse> authorizerTokenResponseResultModel = wechatFeign.authorizerToken(WechatAuthorizerTokenRequest.builder().appId(companyVersionModel.getAppId()).build());
        AssertUtil.isTrue(authorizerTokenResponseResultModel);
        String token = authorizerTokenResponseResultModel.getData().getToken();
        GetAuditstatusResponse response = CodeApi.getLatestAuditStatus(token);
        log.info("获取最新审核结果：{}", response.toString());
        if (response.getErrcode().equals(0)) {
            if (response.getStatus().equals(0)) {
                if (release) {
                    log.info("审核通过，开始发布");
                    companyVersionModel.setState(CompanyVersionEnums.audit_success.getCode());
                    release(companyVersionModel);
                }
            } else {
                if (response.getStatus() == 1) {
                    companyVersionModel.setState(CompanyVersionEnums.audit_err.getCode());
                } else {
                    companyVersionModel.setState(CompanyVersionEnums.in_audit.getCode());
                }
                companyVersionModel.setRemark(response.toString());
                companyVersionMapper.updateByPrimaryKeySelective(companyVersionModel);
            }
        }
        return response;
    }

    @Override
    public BaseResponse release(Integer versionId, String appId) {
        CompanyVersionModel companyVersionModel = companyVersionMapper.selectAccountById(new CompanyVersionModel() {{
            setVersionId(versionId);
            setAppId(appId);
        }});
        if (companyVersionModel.getState().equals(CompanyVersionEnums.release_success.getCode())) {
            log.info("当前小程序没有待发布工作");
        }
        ResultModel<WechatAuthorizerTokenResponse> authorizerTokenResponseResultModel = wechatFeign.authorizerToken(WechatAuthorizerTokenRequest.builder().appId(companyVersionModel.getAppId()).build());
        AssertUtil.isTrue(authorizerTokenResponseResultModel);
        String token = authorizerTokenResponseResultModel.getData().getToken();
        BaseResponse response = CodeApi.release(token);
        log.info("小程序开始发布..........{}", response.toString());
        if (response.getErrcode().equals(0)) {
            companyVersionModel.setState(CompanyVersionEnums.release_success.getCode());
        } else {
            companyVersionModel.setState(CompanyVersionEnums.release_err.getCode());
        }
        companyVersionModel.setRemark(response.toString());
        companyVersionMapper.updateByPrimaryKeySelective(companyVersionModel);
        return response;
    }

    @Override
    public BaseResponse release(CompanyVersionModel companyVersionModel) {
        ResultModel<WechatAuthorizerTokenResponse> authorizerTokenResponseResultModel = wechatFeign.authorizerToken(WechatAuthorizerTokenRequest.builder().appId(companyVersionModel.getAppId()).build());
        AssertUtil.isTrue(authorizerTokenResponseResultModel);
        String token = authorizerTokenResponseResultModel.getData().getToken();
        BaseResponse response = CodeApi.release(token);
        log.info("小程序开始发布..........{}", response.toString());
        if (response.getErrcode().equals(0)) {
            companyVersionModel.setState(CompanyVersionEnums.release_success.getCode());
        } else {
            companyVersionModel.setState(CompanyVersionEnums.release_err.getCode());
        }
        companyVersionModel.setRemark(response.toString());
        companyVersionMapper.updateByPrimaryKeySelective(companyVersionModel);
        return response;
    }

    @Override
    public BaseResponse undoCodeAudit(String appId) {
        ResultModel<WechatAuthorizerTokenResponse> authorizerTokenResponseResultModel = wechatFeign.authorizerToken(WechatAuthorizerTokenRequest.builder().appId(appId).build());
        AssertUtil.isTrue(authorizerTokenResponseResultModel);
        String token = authorizerTokenResponseResultModel.getData().getToken();
        log.info("token:{}", token);
        return CodeApi.undoCodeAudit(token);
    }
}


